//
// Created by hjie on 23-7-23.
//
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <iostream>
#include <memory>

bool ParseSubstr(const std::string & content)
{
    std::stack<char> stack_char;
    std::stack<int> repeat_number_stack;
    std::stack<std::string> substr_stack;

    int number = 0;
    std::string result_content;
    for (auto i = 0; i < content.size(); i++)
    {
        if (content[i] == '[')
        {
            stack_char.push(i);
            continue;
        }
        else if (content[i] == ']')
        {
            std::string substr = content.substr(stack_char.top() + 1, i - stack_char.top() - 1);
            // printf("substr : %s.\n", substr.c_str());
            int num = repeat_number_stack.top();
            repeat_number_stack.pop();
            for (int j = 0; j < num; j++)
            {

            }
            continue;
        }
        else if (content[i] >= '0' && content[i] <= '9')
        {
            number += number * 10 + content[i] - '0';
        }
        else
        {
            // printf("repeat number : %d.\n", number);
            if (number != 0)
            {
                repeat_number_stack.push(number);
            }
            result_content += content[i];
            number = 0;
        }
    }
    return true;
}

bool ParseSubStr(const std::string & content, std::string & result)
{
    std::stack<int> stack_char;
    std::vector<std::string> substr_vec;
    std::vector<int> repeat_number_vec;

    std::string prefix = "";
    std::string suffix = "";

    for (auto i = content.size() - 1; i >= 0; i--)
    {
        if (content[i] == '[' || content[i] == ']' || (content[i] >= '0' && content[i] <= '9'))
        {
            break;
        }
        suffix += content[i];
    }
    for (auto i = 0; i < content.size(); i++)
    {
        if (content[i] == '[' || content[i] == ']' || (content[i] >= '0' && content[i] <= '9'))
        {
            break;
        }
        prefix += content[i];
    }

    std::string one_substr;
    int number = 0;
    for (auto i = 0; i < content.size(); i++)
    {
        if (content[i] == '[')
        {
            stack_char.push(i);
            continue;
        }
        else if (content[i] == ']')
        {
            std::string substr = content.substr(stack_char.top() + 1, i - stack_char.top() - 1);
            std::string res;
            if (!ParseSubStr(substr, res))
            {
                substr_vec.push_back(substr);
                stack_char.pop();
            }
            else
            {
                repeat_number_vec.pop_back();
                substr_vec.pop_back();
                substr_vec.push_back(res);
                stack_char.pop();
            }
            // printf("substr : %s.\n", substr.c_str());
            continue;
        }
        else if (content[i] >= '0' && content[i] <= '9')
        {
            number += number * 10 + content[i] - '0';
        }
        else
        {
            // printf("repeat number : %d.\n", number);
            if (number != 0)
            {
                repeat_number_vec.push_back(number);
            }
            number = 0;
        }
    }
    if (substr_vec.empty())
    {
        return false;
    }
    for (auto i = 0; i < repeat_number_vec.size(); i++)
    {
        if (repeat_number_vec[i] > 0 && i < substr_vec.size())
        {
            std::string substr = substr_vec[i];
            for (auto j = 0; j < repeat_number_vec[i]; j++)
            {
                result += substr;
            }
        }
    }
    result = prefix + result + suffix;
    printf("finally target : %s.\n", result.c_str());
    return true;
}

void StringDecoder()
{
    const std::string code_str1 = "3[a]2[bc]";
    const std::string code_str2 = "3[a2[c]]";
    const std::string code_str3 = "2[abc]3[cd]ef";

    std::string result;
    ParseSubStr(code_str1, result);
    result = "";
    ParseSubStr(code_str2, result);
    result = "";
    ParseSubStr(code_str3, result);
}

int main(int argc, const char * argv[])
{
    StringDecoder();
    return EXIT_SUCCESS;
}